package com.example.netcapture.service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import com.example.netcapture.utils.PackageParser;
import org.pcap4j.core.PcapHandle;
import org.pcap4j.core.Pcaps;
import org.pcap4j.packet.EthernetPacket;
import org.pcap4j.packet.IpV4Packet;
import org.pcap4j.packet.Packet;
import org.pcap4j.packet.TcpPacket;
import org.pcap4j.packet.UdpPacket;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.netcapture.entity.PacketInfo;
import com.example.netcapture.repository.PacketInfoMapper;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class PcapFileParserService extends ServiceImpl<PacketInfoMapper, PacketInfo> {

    /**
     * 解析PCAP文件并保存到数据库
     *
     * @param filePath PCAP文件路径
     * @param networkInterface 网络接口名称（用于记录）
     * @return 解析的数据包数量
     */
    public int parsePcapFileAndSave(String filePath, String networkInterface) {
        return parsePcapFileAndSave(filePath, networkInterface, -1);
    }

    /**
     * 解析PCAP文件并保存到数据库
     *
     * @param filePath PCAP文件路径
     * @param networkInterface 网络接口名称（用于记录）
     * @param maxPackets 最大解析包数量，-1表示无限制
     * @return 解析的数据包数量
     */
    public int parsePcapFileAndSave(String filePath, String networkInterface, int maxPackets) {
        List<PacketInfo> packetInfos = parsePcapFile(filePath, networkInterface, maxPackets);

        if (packetInfos != null && !packetInfos.isEmpty()) {
            // 批量保存到数据库
            saveBatch(packetInfos);
            log.info("成功解析并保存 {} 个数据包到数据库", packetInfos.size());
            return packetInfos.size();
        }

        return 0;
    }

    /**
     * 解析PCAP文件为PacketInfo列表
     *
     * @param filePath PCAP文件路径
     * @param networkInterface 网络接口名称
     * @param maxPackets 最大解析包数量
     * @return PacketInfo列表
     */
    public List<PacketInfo> parsePcapFile(String filePath, String networkInterface, int maxPackets) {
        List<PacketInfo> packetInfos = new ArrayList<>();

        try (PcapHandle handle = Pcaps.openOffline(filePath)) {
            log.info("开始解析PCAP文件: {}", filePath);

            int packetCount = 0;
            while (true) {
                try {
                    // 读取下一个数据包
                    Packet packet = handle.getNextPacket();
                    if (packet == null) {
                        break; // 文件结束
                    }

                    // 解析数据包
                    PacketInfo packetInfo = PackageParser.parsePacket(packet, networkInterface);
                    if (packetInfo != null) {
                        packetInfos.add(packetInfo);
                        packetCount++;
                    }

                    // 检查是否达到最大包数量限制
                    if (maxPackets > 0 && packetCount >= maxPackets) {
                        log.info("达到最大解析包数量限制: {}", maxPackets);
                        break;
                    }

                } catch (Exception e) {
                    log.warn("解析数据包时发生错误，继续处理下一个包", e);
                    continue;
                }
            }

            log.info("PCAP文件解析完成，共解析 {} 个数据包，有效包 {}", packetCount, packetInfos.size());
            return packetInfos;

        } catch (Exception e) {
            log.error("解析PCAP文件失败: {}", filePath, e);
            return null;
        }
    }

}